<?php

namespace app\api\controller;


use app\api\model\Carts;
use app\api\model\Order as OrderModel;
use app\api\model\OrderAction;
use app\api\model\OrderAdd;
use app\api\model\OrderGoods;
use app\api\model\OrderUnion;
use app\api\model\OrderUnionAdd;
use app\api\model\UserCoupon;
use app\common\controller\Api;
use think\Db;

/**
 * 订单接口
 */
class Order extends Api
{
    protected $noNeedLogin = ['epay','addepay','close'];
    protected $noNeedRight = ['*'];

    //计算邮费，判断商品
    public function carts()
    {
        $cart_ids = $this->request->post('ids');

        $date = $this->request->post('date');
        $goods_sku_id = $this->request->post('goods_sku_id');
        if (empty($cart_ids)) {
            $this->error('参数缺失');
        }
        $user_coupon_id = $this->request->post('user_coupon_id/d'); //优惠券

        $orderInfo = [
            'order_sn'    => '',
            'amount'      => 0, //订单金额（包含运费）
            'shippingfee' => 0, //运费
            'goodsprice'  => 0 //商品金额
        ];
        $goodsList = [];

        try {
            list($orderItem, $goodsList) = OrderModel::computeCarts($orderInfo, $cart_ids, $this->auth->id, $user_coupon_id,$date,$goods_sku_id);
            if (empty($goodsList)) {
                throw new \Exception("未找到商品");
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        //$goods_ids = array_column($orderItem,'goods_id');

        foreach ($goodsList as $k=>$v) {
            $goods_list = $v['goods_list'];
            foreach ($goods_list as $item) {
                $item->category_id = $item->goods->category_id;
                $item->goods->visible(explode(',', 'id,title,image,price,marketprice,discountprice'));
                if (isset($item['is_present'])){
                    $item->goods->price = 0;
                }
            }
            $goodsList[$k]['goods_list'] = $goods_list;
        }

        /*foreach ($goodsList as $item) {
            $item->category_id = $item->goods->category_id;
            $item->goods->visible(explode(',', 'id,title,image,price,marketprice,discountprice'));
        }*/
        //获取我的可以使用的优惠券
        $goods_ids = array_column($orderItem, 'goods_id');
        $category_ids = array_column($orderItem, 'category_id');

        $data = [
            //'coupons'          => UserCoupon::myGoodsCoupon($this->auth->id, $goods_ids, $category_ids,$orderInfo['saleamount']),
            //'coupons'          => UserCoupon::myGoodsCoupon($this->auth->id,$orderInfo['saleamount'],$goods_ids),
            'goods_list'       => $goodsList,
            'order_info'       => $orderInfo,
            //'couponTotalPrice' => floatval(!isset($config['shippingfeecoupon']) || $config['shippingfeecoupon'] == 0 ? $orderInfo['goodsprice'] : $orderInfo['amount'])
        ];

        if ($this->auth->id&&$this->auth->level==0){
            $data['coupons'] = UserCoupon::myGoodsCoupon($this->auth->id, $goods_ids, $category_ids,$orderInfo['amount']);
        } else {
            $data['coupons'] = [];
        }

        $this->success('获取成功', $data);
    }

    //提交订单
    public function add()
    {
        $cart_ids = $this->request->post('ids');
        $community_id = $this->request->post('community_id/d'); //小区id
        $user_coupon_id = $this->request->post('user_coupon_id/d'); //id
        $goods_sku_id = $this->request->post('goods_sku_id');
        $date = $this->request->post('date');
        $memo = $this->request->post('memo');
        $receiver = $this->request->post('receiver');//收货人姓名
        $mobile = $this->request->post('mobile');//收货人手机号
        $shippingtime = $this->request->post('shippingtime');//配送时间
        $detail_address = $this->request->post('detail_address'); //详细地址
        if (empty($community_id)) {
            $this->error('请选择小区');
        }
        if (empty($cart_ids)) {
            $this->error('请选择商品');
        }
        if (empty($receiver)) {
            $this->error('请填写收货人姓名');
        }
        if (empty($mobile)) {
            $this->error('请填写收货人手机号');
        }

        //为购物车id
        //校验购物车id 合法
        $row = (new Carts)->where('id', 'IN', $cart_ids)->where('user_id', '<>', $this->auth->id)->find();
        if ($row) {
            $this->error('存在不合法购物车数据');
        }
        $order = null;
        try {
            $order = OrderModel::createOrder($community_id, $this->auth->id, $cart_ids, $user_coupon_id, $memo,$receiver,$mobile,$shippingtime,$date,$goods_sku_id,$detail_address);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('下单成功！', $order);
    }

    //订单列表
    public function lists()
    {

        $param = $this->request->param();
        $param['user_id'] = $this->auth->id;
        $list = OrderModel::tableList($param);

        foreach ($list as $item) {
            $item->append(['status_text']);
            $field = 'id,amount,date,saleamount,paystate,orderstate,shippingstate,order_goods,status,order_sn,status_text,expiretime,endtime,can_refund,payamount';
            $item->visible(explode(',', $field));
            $item->expiretime = $item->expiretime - time();
            /*if($item->endtime>time()){
                $item->can_refund = 1;
                $date = date('Y-m-d',time());
                $tomorrow = date('Y-m-d', strtotime('+1 day'));
                if ($item->date==$date){
                    $item->can_refund = 0;
                    //$this->error('已截单,当天订单不可申请退款');
                } elseif ($item->date==$tomorrow){
                    $item->can_refund = 0;
                    //$this->error('已截单,隔天订单不可申请退款');
                }
            }*/

            //前一天截单日期之前能退，之后都不能退
            $item->can_refund = 0;
            if ($item->shippingstate == 0 && $item->orderstate == 0 && $item->paystate == 1) {
                $cut_off_time = nl2br(Config('site.cut_off_time'));
                $end_time = strtotime("-1 day", strtotime($item->date));
                $end_time = date('Y-m-d '.$cut_off_time, $end_time);
                if (time() < strtotime($end_time)) {
                    $item->can_refund = 1;
                }
            }

        }
        $this->success('获取成功', $list);
    }

    //支付弹出框订单内容
    public function popup()
    {
        $order_sn = $this->request->post('order_sn');

        $order_info = \app\api\model\Order::get(['order_sn'=>$order_sn]);

        $union_order = OrderUnion::where('FIND_IN_SET(:order_id,order_id)',['order_id' => $order_info->id])->find();

        //$order_list = \app\api\model\Order::where('id','in',$union_order->order_id)->select();
        $param = [
            'id'=> $union_order->order_id,
            'user_id'=>$this->auth->id
        ];
        $order_list = OrderModel::newtableList($param);

        foreach ($order_list as $item) {
            $item->append(['status_text']);
            $field = 'id,amount,date,saleamount,paystate,orderstate,shippingstate,order_goods,status,status_text';
            $item->visible(explode(',', $field));
        }
        $union_order->expiretime = $union_order->expiretime - time();
        $data = [
            'order_list' => $order_list,
            'union_order' => $union_order
        ];

        $this->success('获取成功', $data);
    }

    //取消订单
    public function singlecancel()
    {
        $order_sn = $this->request->post('order_sn');
        if (!$order_sn) {
            $this->error('参数错误');
        }
        $order = OrderModel::getByOrderSn($order_sn);
        if (empty($order)) {
            $this->error('订单不存在');
        }
        if ($order->user_id != $this->auth->id) {
            $this->error('不能越权操作');
        }
        if ($order->status == 'hidden') {
            $this->error('订单已失效！');
        }
        //可以取消
        if (!$order->paystate && !$order->orderstate) {
            // 启动事务
            Db::startTrans();
            try {
                $order->orderstate = 1;
                $order->canceltime = time();
                $order->save();
                foreach ($order->order_goods as $item) {
                    $sku = $item->sku;
                    $goods = $item->goods;
                    //商品库存恢复
                    if ($sku) {
                        $sku->setInc('stocks', $item->nums);
                    }
                    if ($goods) {
                        $goods->setInc('stocks', $item->nums);
                    }
                }
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error('订单取消失败');
            }
            //记录操作
            OrderAction::push($order->order_sn, '系统', '订单取消成功');
            $this->success('订单取消成功！', $order['status']);
        } else {
            $this->error('订单不允许取消');
        }
    }

    //取消订单
    public function cancel()
    {
        $order_sn = $this->request->post('order_sn');
        if (!$order_sn) {
            $this->error('参数错误');
        }
        $orderInfo = OrderUnion::get(['order_sn'=>$order_sn]);

        if (empty($orderInfo)) {
            $this->error('订单不存在');
        }
        if ($orderInfo->user_id != $this->auth->id) {
            $this->error('不能越权操作');
        }
        if ($orderInfo->orderstate == 2) {
            $this->error('订单已失效！');
        }
        //可以取消
        if (!$orderInfo->pay_status && !$orderInfo->orderstate) {
            // 启动事务
            Db::startTrans();
            try {
                $orderInfo->orderstate = 1;
                $orderInfo->canceltime = time();
                $orderInfo->save();
                $order_list = \app\api\model\Order::where('id','in',$orderInfo->order_id)->select();
                foreach ($order_list as $k=>$v){
                    $order = OrderModel::getByOrderSn($v['order_sn']);
                    $order->orderstate = 1;
                    $order->canceltime = time();
                    $order->save();
                    foreach ($order->order_goods as $item) {
                        $sku = $item->sku;
                        $goods = $item->goods;
                        //商品库存恢复
                        if ($sku) {
                            $sku->setInc('stocks', $item->nums);
                        }
                        if ($goods) {
                            $goods->setInc('stocks', $item->nums);
                        }
                    }
                }

                //恢复优惠券
                UserCoupon::resetUserCoupon($orderInfo->user_coupon_id, $orderInfo->order_sn);
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error('订单取消失败');
            }
            //记录操作
            OrderAction::push($orderInfo->order_sn, '系统', '订单取消成功');
            $this->success('订单取消成功！');
        } else {
            $this->error('订单不允许取消');
        }
    }

    //订单详情
    public function detail()
    {
        $order_sn = $this->request->param('order_sn');
        if (empty($order_sn)) {
            $this->error('参数缺失');
        }
        $order = OrderModel::getOrderDetail($order_sn, $this->auth->id);
        if (empty($order)) {
            $this->error('未找到订单');
        }
        $order_goods = OrderGoods::where(['order_sn'=>$order_sn])
            ->where('salestate','<>',4)->select();
        $order['order_goods'] = $order_goods;
        /*foreach ($order['order_goods'] as $k=>$v){
            if ($v->salestate==4)unset($order['order_goods'][$k]);
        }*/
        //$order->append(['status_text']);
        $order->hidden(explode(',', 'method,transactionid,updatetime,deletetime'));
        $order->expiretime = $order->expiretime - time();

        $union_order = OrderUnion::where('FIND_IN_SET(:order_id,order_id)',['order_id' => $order->id])->find();
        $order_list = \app\api\model\Order::where('id','in',$union_order->order_id)
            ->field('id,order_sn,date')
            ->order('date asc')->select();
        $order->order_list = $order_list;

        $order->can_refund = 0;

        if ($order->shippingstate == 0 && $order->orderstate == 0 && $order->paystate == 1) {
            $cut_off_time = nl2br(Config('site.cut_off_time'));
            $end_time = strtotime("-1 day", strtotime($order->date));
            $end_time = date('Y-m-d '.$cut_off_time, $end_time);
            if (time() < strtotime($end_time)) {
                $order->can_refund = 1;
            }
        }

//        if($order->endtime>time()){
//            $order->can_refund = 1;
//            $date = date('Y-m-d',time());
//            $tomorrow = date('Y-m-d', strtotime('+1 day'));
//            if ($order->date==$date){
//                $order->can_refund = 0;
//                //$this->error('已截单,当天订单不可申请退款');
//            } elseif ($order->date==$tomorrow){
//                $order->can_refund = 0;
//                //$this->error('已截单,隔天订单不可申请退款');
//            }
//        }
        $this->success('', $order);
    }

    //修改订单的减少餐品信息
    public function changeDetail()
    {
        $changeinfo = $this->request->post('changeinfo');
        $order_sn = $this->request->post('order_sn');
        $addgoods = $this->request->post('addgoods');
        if (empty($changeinfo)) {
            $this->error('参数缺失');
        }
        $order = OrderModel::getDetail($order_sn, $this->auth->id);
        if (empty($order)) {
            $this->error('未找到订单');
        }
        //if ($order->endtime<time())$this->error('可修改时间已过');
        $order_model = new \app\api\model\Order();

        $res = $order_model->changeDetail($changeinfo,$order_sn,$addgoods,$this->auth->id);

        $this->success('',$res);
    }

    //修改订单
    public function edit()
    {
        $addgoods = $this->request->post('addgoods');
        $changeinfo = $this->request->post('changeinfo');
        if (empty($addgoods)) {
            $this->error('参数缺失');
        }
        $order_model = new \app\api\model\Order();

        $res = $order_model->editOrder($changeinfo,$addgoods,$this->auth->id);

        $this->success('', $res);
    }

    //新增餐品的付款
    public function payAddOrder()
    {
        $order_sn = $this->request->post('order_sn');
        $paytype = $this->request->post('paytype');


        $orderInfo = OrderUnionAdd::get(['order_sn'=>$order_sn]);
        if (!$orderInfo) {
            $this->error("未找到指定的订单");
        }
        if ($orderInfo['pay_status']) {
            $this->error("订单已经支付，请勿重复支付");
        }

        if ($paytype=='wechat'){
            $openid = $this->auth->wechat_open_id;
            $response = null;
            try {
                $response = OrderUnionAdd::pay($order_sn, $this->auth->id, $paytype, 'miniapp', $openid);
            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
            $this->success("请求成功", $response);
        } else {

            if ($this->auth->money<$orderInfo['saleamount']){
                $this->error('余额不足');
            }
            $res = OrderUnionAdd::settle($order_sn, $orderInfo['saleamount'], '','balance');

            $this->success("请求成功", $res);
        }
    }


    //订单支付
    public function pay()
    {
        $order_sn = $this->request->post('order_sn');
        $paytype = $this->request->post('paytype');
        $returnurl = $this->request->post('returnurl', '', 'trim');

        $openid = $this->auth->wechat_open_id;

        $orderInfo = OrderUnion::get(['order_sn'=>$order_sn]);
        if (!$orderInfo) {
            $this->error("未找到指定的订单");
        }

        if ($orderInfo['pay_status']) {
            $this->error("订单已经支付，请勿重复支付");
        }
        //订单过期
        if (!$orderInfo['orderstate'] && time() > $orderInfo['expiretime']) {
            // 启动事务
            Db::startTrans();
            try {
                $order_list = \app\api\model\Order::where('id','in',$orderInfo->order_id)->select();
                foreach ($order_list as $k=>$v){
                    \app\api\model\Order::update(['orderstate' => 2],['id' => $v['id']]);
                    OrderGoods::setGoodsStocksInc($v['order_sn']);
                }
                $orderInfo->save(['orderstate' => 2]);

                //恢复优惠券
                UserCoupon::resetUserCoupon($orderInfo->user_coupon_id, $orderInfo->order_sn);
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
            }
            $this->error("订单已失效");
        }

        if ($paytype=='wechat'){
            $response = null;
            try {
                $response = OrderUnion::pay($order_sn, $this->auth->id, $paytype, 'miniapp', $openid, '', $returnurl);

            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
            $this->success("请求成功", $response);
        } else {

            if ($this->auth->money<$orderInfo['saleamount']){
                $this->error('余额不足');
            }

            $res = OrderUnion::settle($order_sn, $orderInfo['saleamount'], '','balance');

            $this->success("请求成功", $res);
        }


    }

    public function addepay()
    {
        $type = $this->request->param('type');
        $paytype = $this->request->param('paytype');
        if ($type == 'notify') {
            $pay = \addons\epay\library\Service::checkNotify($paytype);
            if (!$pay) {
                echo '签名错误';
                return;
            }
            $data = $pay->verify();
            try {
                $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
                OrderUnionAdd::settle($data['out_trade_no'], $payamount, $paytype == 'alipay' ? $data['trade_no'] : $data['transaction_id'],'wechatpay');
            } catch (\Exception $e) {
                \think\Log::write($e->getMessage(), 'epay');
            }
            echo $pay->success();
        }
        return;
    }

    /**
     * @ DateTime 2021-06-01
     * @ 支付回调
     * @return void
     */
    public function epay()
    {
        $type = $this->request->param('type');
        $paytype = $this->request->param('paytype');
        if ($type == 'notify') {
            $pay = \addons\epay\library\Service::checkNotify($paytype);
            if (!$pay) {
                echo '签名错误';
                return;
            }
            $data = $pay->verify();
            try {
                $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
                OrderUnion::settle($data['out_trade_no'], $payamount, $paytype == 'alipay' ? $data['trade_no'] : $data['transaction_id'],'wechatpay');
            } catch (\Exception $e) {
                \think\Log::write($e->getMessage(), 'epay');
            }
            echo $pay->success();
        }
        return;
    }


    public function recently_placed()
    {
        $community_id = $this->request->post('community_id'); //小区ID
        $order = \app\api\model\Order::where(['user_id'=>$this->auth->id,'community_id'=>$community_id])
            ->field('mobile,receiver,paytype,detail_address')
            ->order('createtime desc')->find();
        $this->success('',$order);
    }

    //未支付关闭
    public function close()
    {
        $order_sn = $this->request->post('order_sn');

        $orderInfo = OrderUnion::get(['order_sn'=>$order_sn]);
        if (!$orderInfo) {
            $this->error("未找到指定的订单");
        }

        if ($orderInfo['pay_status']) {
            $this->error("订单已经支付");
        }
        if (!$orderInfo['orderstate']){
            Db::startTrans();
            try {
                $order_list = \app\api\model\Order::where('id','in',$orderInfo->order_id)->select();
                foreach ($order_list as $k=>$v){
                    \app\api\model\Order::update(['orderstate' => 2],['id' => $v['id']]);
                    OrderGoods::setGoodsStocksInc($v['order_sn']);
                }
                $orderInfo->save(['orderstate' => 2]);

                //恢复优惠券
                UserCoupon::resetUserCoupon($orderInfo->user_coupon_id, $orderInfo->order_sn);
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
            }
        }

        $this->error("订单已失效");
    }
}
